package com.dragoncombin.homework;

import java.util.Scanner;

public class Problem02 {

    // 定义用于记录棋局二维数组， 执黑先行，棋盘上黑子记为b， 白字记为w
    private int[][] arr = new int[16][16];
    // 某一轮下棋的玩家
    private boolean isBlackplayer = true;
    // 某一轮下棋的落子的位置
    private int row;
    private int column;
    // 统计下棋的轮数
    private int round = 0;


    // 定义成员方法实现棋盘的绘制
    public void draw() {
        for(int i = 0; i < 17; i++) {
            for(int j = 0; j < 17; j++) {
                if(0 == i) {
                    if(0 == j) {
                        System.out.print("  ");
                    }else {
                        System.out.print(Integer.toHexString(j - 1) + " ");
                    }
                }else if(0 == j) {
                    System.out.print(Integer.toHexString(i - 1) + " ");
                }else {
                    if(0 == arr[i - 1][j - 1]) System.out.print("+ ");
                    else if(1 == arr[i - 1][j - 1]) System.out.print("b ");
                    else System.out.print("w ");
                }
            }
            System.out.println();
        }

    }

    // 定义成员方法实现 提示黑方和白方分别下棋并重新绘制棋盘
    public void play() {
        // 根据 player提示黑白方输入落子位置，并修改二维数组对应的值
        // 黑子在二维数组中用数字1表示，白字用数字-1表示
        Scanner in = new Scanner(System.in);
        while(true) {
            System.out.println("请 " + (isBlackplayer? "black" : "white") + " 方输入落子位置(行列空格隔开): ");
            row = in.nextInt(16);
            column = in.nextInt(16);
            try {
                if (0 != arr[row][column]) {
                    System.out.println("该位置已有棋子，请重新下棋");
                } else if(isBlackplayer){
                    arr[row][column] = 1;  // 将该位置写入表示黑子的1
                    round++;               // 进行的轮数增1
                    break;
                } else {
                    arr[row][column] = -1; // 将该位置写入表示白子的-1
                    round++;
                    break;
                }
            } catch (ArrayIndexOutOfBoundsException e) {
                System.out.println("该位置超出棋盘范围，请重新下棋");
            }
        }

        // 重绘棋盘
        draw();
    }

    // 定义成员方法实现 每当一方下棋后判断是否获胜
    // 根据该轮玩家player和该玩家落子的位置row,column判断是否获胜
    public boolean checkWin(int x, int y) {
        // 1. 本轮下棋的玩家player,其落子的位置row, column
        // 水平方向
        for(int i = -4; i <= 0; i++) {
            int cnt = 0;
            if(y + i < 0 || y + i + 5 > 16) continue;
            for(int j = i; j < i + 5; j++) {
                if(arr[x][y] != arr[x][y + j]) break;
                cnt++;
            }
            if(cnt >= 5) {
                return true;
            }
        }
        // 竖直方向
        for(int i = -4; i <= 0; i++) {
            int cnt = 0;
            if(x + i < 0 || x + i + 5 > 16) continue;
            for(int j = i; j < i + 5; j++) {
                if(arr[x][y] != arr[x + j][y]) break;
                cnt++;
            }
            if(cnt >= 5) {
                return true;
            }
        }
        // 左上到右下方向
        for(int i = -4; i <= 0; i++) {
            int cnt = 0;
            if(x + i < 0 || x + i + 5 > 16 || y + i < 0 || y + i + 5 > 16) continue;
            for(int j = i; j < i + 5; j++) {
                if(arr[x][y] != arr[x + j][y + j]) break;
                cnt++;
            }
            if(cnt >= 5) {
                return true;
            }
        }
        // 右上到左下方向
        for(int i = -4; i <= 0; i++) {
            int cnt = 0;
            if(x + i < 0 || x + i + 5 > 16 || y - i > 16 || y - i - 5 < 0) continue;
            for(int j = i; j < i + 5; j++) {
                if(arr[x][y] != arr[x + j][y - j]) break;
                cnt++;
            }
            if(cnt >= 5) {
                return true;
            }
        }
        return false;
    }


    public static void main(String[] args) {

        // 1. 声明Problem02类型引用指向该类对象
        Problem02 p = new Problem02();
        System.out.println("-----五子棋游戏------");
        // 2. 绘制棋盘
        p.draw();
        // 3. 进入游戏循环
        while(true) {
            // 4. 提示玩家输入，并重新绘制棋盘
            p.play();
            // 5. 判断是否当前玩家胜出
            if(p.checkWin(p.row, p.column)) { // 有玩家胜出，跳出循环
                System.out.println("恭喜, " + ((p.isBlackplayer) ? "黑方" : "白方") + "获胜！");
                break;
            } else if(p.round >= 256) { // 平局的情况，进行的轮数超过棋盘中所有点的个数，跳出循环
                System.out.println("平局。。再来一局，一决高下");
                break;
            }
            // 6. 切换玩家
            p.isBlackplayer = !p.isBlackplayer;
        }
    }
}
